<?php
namespace Core\Libs\Http;

class Header {

	protected $charset = '';
	protected $charsets = array();
	protected $contentType = '';
	protected $contentTypes = array();
	protected $encoding = '';
	protected $language = '';
	protected $responseType = '';
	protected $methodToResponse = 'responseOfView';
	protected $code = 200;
	protected $isSent = FALSE;

	protected $codes = array(

								100 => '100 Continue',
								101 => '101 Switching Protocols',
								102 => '102 Processing',

								200 => '200 OK',
								201 => '201 Created',
								202 => '202 Accepted',
								203 => '203 Non-Authoritative Information',
								204 => '204 No Content',
								205 => '205 Reset Content',
								206 => '206 Partial Content',
								207 => '207 Multi-Status',

								300 => '300 Multiple Choices',
								301 => '301 Moved Permanently',
								302 => '302 Found',
								303 => '303 See Other',
								304 => '304 Not Modified',
								305 => '305 Use Proxy',
								306 => '306 (Unused)',
								307 => '307 Temporary Redirect',

								400 => '400 Bad Request',
								401 => '401 Unauthorized',
								402 => '402 Payment Granted',
								403 => '403 Forbidden',
								404 => '404 File Not Found',
								405 => '405 Method Not Allowed',
								406 => '406 Not Acceptable',
								407 => '407 Proxy Authentication Required',
								408 => '408 Request Time-out',
								409 => '409 Conflict',
								410 => '410 Gone',
								411 => '411 Length Required',
								412 => '412 Precondition Failed',
								413 => '413 Request Entity Too Large',
								414 => '414 Request-URI Too Large',
								415 => '415 Unsupported Media Type',
								416 => '416 Requested range not satisfiable',
								417 => '417 Expectation Failed',
								418 => '',
								419 => '',
								420 => '',
								421 => '',
								422 => '422 Unprocessable Entity',
								423 => '423 Locked',
								424 => '424 Failed Dependency',

								500 => '500 Internal Server Error',
								501 => '501 Not Implemented',
								502 => '502 Bad Gateway',
								503 => '503 Service Unavailable',
								504 => '504 Gateway Time-out',
								505 => '505 HTTP Version not supported',
								506 => '',
								507 => '507 Insufficient Storage'
							);

	protected $mimeTypes = array(

							'javascript'	=> 'text/javascript',
							'js'			=> 'text/javascript',
							'json'			=> 'application/json',
							'css'			=> 'text/css',

							'html'			=> array('text/html', '*/*'),

							'text'			=> 'text/plain',
							'txt'			=> 'text/plain',

							'csv'			=> array('application/vnd.ms-excel', 'text/plain'),

							'form'			=> 'application/x-www-form-urlencoded',
							'file'			=> 'multipart/form-data',

							'xhtml'			=> array('application/xhtml+xml', 'application/xhtml', 'text/xhtml'),

							'xhtml-mobile'	=> 'application/vnd.wap.xhtml+xml',

							'xml'			=> array('application/xml', 'text/xml'),

							'rss'			=> 'application/rss+xml',
							'atom'			=> 'application/atom+xml',
							'amf'			=> 'application/x-amf',

							'wap'			=> array(
												'text/vnd.wap.wml',
												'text/vnd.wap.wmlscript',
												'image/vnd.wap.wbmp'
												),

							'wml'			=> 'text/vnd.wap.wml',
							'wmlscript'		=> 'text/vnd.wap.wmlscript',
							'wbmp'			=> 'image/vnd.wap.wbmp',
							'pdf'			=> 'application/pdf',
							'zip'			=> 'application/x-zip',
							'tar'			=> 'application/x-tar'
	);

	public function setContentType($contentType = 'text/html') {

		$this->contentType = $contentType;

		return $this;
	}

	public function getContentType() {

		return $this->contentType;
	}

	public function setCharset($charset = 'utf-8') {

		$this->charset = $charset;

		return $this;
	}

	public function getCharset() {

		return $this->charset;
	}

	public function setEncoding($encoding = NULL) {

		$this->encoding = $encoding;

		return $this;
	}

	public function getEncoding() {

		return $this->encoding;
	}

	public function setLanguage($language = NULL) {

		$this->language = $language;

		return $this;
	}

	public function getLanguage() {

		return $this->language;
	}

	public function setMethodToResponse($method = 'responseOfView') {

		$this->methodToResponse = $method;

		return $this;
	}

	public function getMethodToResponse() {

		return $this->methodToResponse;
	}

	public function setResponseType($responseType = 'html') {

		$this->responseType = $responseType;
	}

	public function getResponseType() {

		return $this->responseType;
	}

	public function setCode($code = 200) {

		$this->code = $code;

		return $this;
	}

	public function getCode() {

		return $this->code;
	}

	public function getMimeTypes($type = 'html') {

		if(array_key_exists($type, &$this->mimeTypes)) {

			return $this->mimeTypes[$type];
		}

		return NULL;
	}

	protected function mapOfQuality($arrayMap = array(), $returnString = FALSE) {

		if(!is_array($arrayMap)) {

			return FALSE;
		}

		else {

			$q = 0.9;

			foreach($arrayMap as $i => $map) {

				$arrayMap[$i] = $map . '; ' . 'q=' . $q;
				$q -= 0.1;
			}
		}

		if($returnString) {

			$arrayMap =& implode(', ', &$arrayMap);
		}

		return $arrayMap;
	}

	public function prefers($types = array(), $accepts = array(), $default = 'text/html', $isMime = TRUE) {

		if(!is_array($accepts)) {

			if(empty($accepts)) {

				$accepts = $default;
			}

			$accepts = array($accepts);
		}

		if(empty($types)) {

			return $accepts[0];
		}

		elseif(!is_array($types)) {

			$types = array($types);
		}

		$prefers = array();

		if($isMime) {

			foreach($types as $type) {

				$prefers = array_merge($prefers, (array)array_diff((array)$this->mimeTypes[$type], $prefers));
			}
		}

		else {

			$prefers = $types;
		}

		$prefers = array_values((array)array_intersect($accepts, (array)$prefers));
		unset($types, $type, $accepts, $default, $isMime);

		return $prefers[0];
	}

	protected function mapType($ctype) {

		if(is_array($ctype)) {

			$out = array();

			foreach($ctype as $t) {

				$out[] = $this->mapType($t);
			}

			return $out;
		}

		else {

			$keys = array_keys($this->mimeTypes);
			$count = count($keys);

			for($i = 0; $i < $count; $i++) {

				$name = $keys[$i];
				$type = $this->mimeTypes[$name];

				if(is_array($type) && in_array($ctype, $type)) {

					return $name;
				}

				elseif(!is_array($type) && $type == $ctype) {

					return $name;
				}
			}

			return $ctype;
		}
	}
}

class RequestHeader extends \Core\Libs\Http\Header {

	private $extension = NULL;
	private $initialized = FALSE;
	private $acceptMimeTypes = array();
	private $acceptCharsets = array();
	private $acceptEncodings = array();
	private $acceptLanguages = array();

	public function __construct() {

		//$this->initHeaders();
		$this->acceptCharsets('utf-8');
		$this->acceptMimeTypes();
		$this->acceptLanguages();
		$this->acceptEncodings(NULL);
	}

	public function getExtension() {

		return $this->extension;
	}

	public function getAcceptMimeTypes() {

		return $this->acceptMimeTypes;
	}

	public function getAcceptCharsets() {

		return $this->acceptCharsets;
	}

	public function getAcceptEncodings() {

		return $this->acceptEncodings;
	}

	public function getAcceptLanguages() {

		return $this->acceptLanguages;
	}

	public function acceptMimeTypes($mimeTypes = NULL) {

		if(empty($mimeTypes)) {

			$this->acceptMimeTypes = explode(',', $_SERVER['HTTP_ACCEPT']);
		}

		elseif(!is_array($mimeTypes)) {

			$this->acceptMimeTypes = explode(',', $mimeTypes);
		}

		else {

			$this->acceptMimeTypes = $mimeTypes;
		}

		foreach($this->acceptMimeTypes as $i => $type) {

			$type = trim($type);

			if(strpos($type, ';')) {

				$type = explode(';', $type);
				$this->acceptMimeTypes[$i] = trim($type[0]);
			}
		}
	}

	protected function getAccept($default = NULL) {

		
	}

	public function acceptCharsets($default = 'utf-8') {

		if(func_num_args() < 1) {

			$default = \Core\Uses\Ler('Core.coding.output');
		}

		$this->acceptCharsets = explode(',', $_SERVER['HTTP_ACCEPT_CHARSET']);

		foreach($this->acceptCharsets as $i => $type) {

			if(strpos($type, ';')) {

				$type = explode(';', $type);
				$type[0] = trim($type[0]);

				if(strtolower($type[0]) === strtolower($default)) {

					unset($this->acceptCharsets[$i]);
					array_unshift($this->acceptCharsets, strtoupper($type[0]));
				}

				else {

					$this->acceptCharsets[$i] = strtoupper($type[0]);
				}
			}

			else {

				$this->acceptCharsets[$i] = strtoupper(trim($type));
			}
		}

		if(count($this->acceptCharsets) < 1 || (count($this->acceptCharsets) === 1 && empty($this->acceptCharsets[0]))) {

			$this->acceptCharsets[0] = strtoupper($default);
		}
	}

	public function acceptEncodings($default = NULL) {

		$this->acceptEncodings = explode(',', $_SERVER['HTTP_ACCEPT_ENCODING']);

		foreach($this->acceptEncodings as $i => $type) {

			$type = trim($type);

			if(strtolower($type) === strtolower($default)) {

				unset($this->acceptEncodings[$i]);
				array_unshift($this->acceptEncodings, strtolower($type));
			}

			else {

				$this->acceptEncodings[$i] = strtolower($type);
			}
		}

		if(count($this->acceptCharsets) < 1) {

			$this->acceptCharsets[0] = NULL;
		}
	}

	public function acceptLanguages($default = 'pt-br') {

		if(func_num_args() < 1) {

			$default = \Core\Uses\Ler('Core.lang.output');
		}

		$this->acceptLanguages = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);

		foreach($this->acceptLanguages as $i => $type) {

			if(strpos($type, ';')) {

				$type = explode(';', $type);
				$type[0] = trim($type[0]);

				if(strtolower($type[0]) === strtolower($default)) {

					unset($this->acceptLanguages[$i]);
					array_unshift($this->acceptLanguages, strtolower($type[0]));
				}

				else {

					$this->acceptLanguages[$i] = strtolower($type[0]);
				}
			}

			else {

				$this->acceptLanguages[$i] = strtolower(trim($type));
			}
		}

		if(count($this->acceptLanguages) < 1 || (count($this->acceptLanguages) === 1 && empty($this->acceptLanguages[0]))) {

			$this->acceptLanguages[0] = strtolower($default);
		}
	}

	public function getHeaders() {

		return $this->headers;
	}

	public function getRequestMethod() {

		return strtoupper($_SERVER['REQUEST_METHOD']);
	}

	public function isPost() {

		return ($this->getRequestMethod() === 'POST') ? TRUE : FALSE;
	}

	public function isGet() {

		return ($this->getRequestMethod() === 'GET') ? TRUE : FALSE;
	}

	public function isPut() {

		return ($this->getRequestMethod() === 'PUT') ? TRUE : FALSE;
	}

	public function isDelete() {

		return ($this->getRequestMethod() === 'DELETE') ? TRUE : FALSE;
	}

	public function isFlash() {

		return (preg_match('/^(Shockwave|Adobe) Flash/', $_SERVER['HTTP_USER_AGENT']) == 1);
	}

	public function isAjax() {

		return ($_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest') ? TRUE : FALSE;
	}
}

class ResponseHeader extends \Core\Libs\Http\Header {

	private $RequestHeader = NULL;
	private $headers = array();
	private $responseCode = '200';
	private $overwriteHeader = FALSE;
	private $readOnly = FALSE;

	public function __construct($RequestHeader = NULL) {

		if(empty($RequestHeader)) {

			$this->RequestHeader = new \Core\Libs\Http\RequestHeader();
		}

		else {

			$this->RequestHeader = $RequestHeader;
			unset($RequestHeader);
		}

		$this->initHeaders();
	}

	private function initHeaders() {

		$headers = headers_list();

		foreach($headers as $header) {

			$header = explode(':', $header, 2);
			$this->headers[$header[0]] = ltrim($header[1]);
		}

		if($this->readOnly) {

			return;
		}

		$this->getDefaultHeaders();
		unset($headers, $header);
	}

	public function getDefaultHeaders() {

		@header('Content-Type: ' . $this->getContentType() . '; charset=' . $this->getCharset(), TRUE);
		//@header('Content-Encoding: ' . $this->getEncoding(), TRUE);
		@header('Content-Language: ' . $this->getLanguage(), TRUE);
	}

	public function setOverwriteHeader($overwriteHeader = FALSE) {

		$this->overwriteHeader = $overwriteHeader;

		return $this;
	}

	public function setReadOnly($readOnly = FALSE) {

		$this->readOnly = $readOnly;
	}

	public function isReadOnly() {

		return $this->readOnly;
	}

	public function getHeaders($initHeaders = FALSE) {

		if($initHeaders) {

			$this->initHeaders();
		}

		return $this->headers;
	}

	public function getCharset($defaultCharset = 'UTF-8') {

		if(empty($this->charset)) {

			if(func_num_args() < 1) {

				$defaultCharset = strtoupper(\Core\Uses\Ler('Core.coding.output'));
			}

			else {

				$defaultCharset = strtoupper($defaultCharset);
			}

			$this->charset = $this->prefers($defaultCharset, $this->RequestHeader->getAcceptCharsets(), $defaultCharset, FALSE);

			if(empty($this->charset)) {

				$this->charset = $defaultCharset;
			}
		}

		return $this->charset;
	}

	public function getContentType($contentType = 'text/html') {

		if(empty($this->contentType)) {

			$this->contentType = $this->prefers($this->getResponseType($contentType), $this->RequestHeader->getAcceptMimeTypes(), $contentType, TRUE);

			if(empty($this->contentType)) {

				$this->contentType = $contentType;
			}
		}

		return $this->contentType;
	}

	public function getEncoding($encoding = 'deflate') {

		if(empty($this->encoding)) {

			$this->encoding = $this->prefers($encoding, $this->RequestHeader->getAcceptEncodings(), NULL, FALSE);
		}

		return $this->encoding;
	}

	public function getLanguage($language = 'pt-br') {

		if(empty($this->language)) {

			$this->language = $this->prefers($language, $this->RequestHeader->getAcceptLanguages(), NULL, FALSE);
		}

		return $this->language;
	}

	public function getResponseType($defaultContentType = 'text/html') {

		if(empty($this->responseType)) {

			if(func_num_args() < 1) {

				$this->responseType = $this->mapType($this->RequestHeader->getAcceptMimeTypes());
			}

			else {

				$this->responseType = $this->mapType($defaultContentType);
			}

			if(is_array($this->responseType)) {

				$this->responseType = $this->responseType[0];
			}
		}

		return $this->responseType;
	}

	public function getResponseTypes($defaultContentType = 'text/html') {

		if(func_num_args() < 1) {

			return $this->mapType($this->RequestHeader->getAcceptMimeTypes());
		}

		else {

			return $this->mapType($defaultContentType);
		}
	}

	public function loadResponse($defaultContentType = 'html') {

		if($this->readOnly) {

			return;
		}

		$contentType = $this->prefers($defaultContentType, $this->RequestHeader->getAcceptMimeTypes());

		if(empty($contentType)) {

			$contentType = $this->mimeTypes[$defaultContentType];

			if(is_array($contentType)) {

				$contentType = $contentType[0];
			}

			if(empty($contentType)) {

				$contentType = 'text/html';
				$defaultContentType = 'html';
			}
		}

		$this->contentType = $contentType;
		$this->responseType = $defaultContentType;
		$this->getDefaultHeaders();

		return $contentType;
	}

	public function loadTypeOfResponse($defaultContentType = 'html') {

		if($this->readOnly) {

			return;
		}

		if(array_key_exists($defaultContentType, $this->mimeTypes)) {

			$this->RequestHeader->acceptMimeTypes($this->mimeTypes[$defaultContentType]);
			$this->getDefaultHeaders();
			$this->responseType = NULL;
			$this->contentType = NULL;

			return TRUE;
		}

		return FALSE;
	}

	public function restoreHeaders($headers = array(), $overwrite = TRUE) {

		foreach($headers as $header) {

			@header($header, $overwrite);
		}
	}

	public function get($header) {

		$headers = $this->getHeaders(TRUE);
		$header = $headers[$header];
		unset($headers);

		return $header;
	}

	public function add($header, $content = '', $overwrite = FALSE) {

		if($this->readOnly) {

			return;
		}

		if(func_num_args() < 3) {

			$overwrite = $this->overwriteHeader;
		}

		if(!array_key_exists($header, $this->getHeaders(TRUE)) || $overwrite) {

			@header($header . ': ' . $content, $overwrite);
			return TRUE;
		}

		return FALSE;
	}

	public function remove($header, $removeOfHeader = FALSE) {

		if($this->readOnly) {

			return;
		}

		if(array_key_exists($header, $this->getHeaders(TRUE))) {

			@header_remove($header);
			return TRUE;
		}

		return FALSE;
	}

	public function merge($header, $content = '') {

		if($this->readOnly) {

			return;
		}

		if(array_key_exists($header, $this->getHeaders(TRUE))) {

			@header($header . ': ' . $content, FALSE);
			unset($header, $content);
			return TRUE;
		}

		unset($header, $content);
		return FALSE;
	}

	public function isSent() {

		return headers_sent();
	}

	public function sent($file, $line = 1) {

		headers_sent($file, $line);
	}

	public function send($file, $line = 1) {

		$this->sent($file, $line);
	}

	private function formatHeaders() {

		if(!is_array($this->headers)) {

			$this->headers = array();
		}

		foreach($this->headers as $header => $content) {

			@header($header, $content);
		}
	}
}

class Http {

	protected $headers = array();
	private $httpVersion = '1.1';
	private $RequestHeader = NULL;
	private $ResponseHeader = NULL;

	public function __construct() {

		$this->RequestHeader = new RequestHeader();

		if(isset($_SERVER['SERVER_PROTOCOL'])) {

			$this->setHttpVersion(substr($_SERVER['SERVER_PROTOCOL'], -3));
		}
	}

	public function RequestHeader() {

		if(empty($this->RequestHeader)) {

			$this->RequestHeader = new RequestHeader();
		}

		return $this->RequestHeader;
	}

	public function ResponseHeader() {

		if(empty($this->ResponseHeader)) {

			$this->ResponseHeader = new ResponseHeader($this->RequestHeader);
		}

		return $this->ResponseHeader;
	}

	public function getHeaders() {

		return $this->headers;
	}

	final public function setHttpVersion($version = 1.1) {

		$version = round((float)$version, 1);

		if($version < 1.0 || $version > 1.1) {

			return FALSE;
		}

		$this->httpVersion = sprintf('%0.1f', $version);
		return TRUE;
	}

	final public function getHttpVersion() {

		return $this->httpVersion;
	}

	public function redirect($url = NULL, $top = FALSE, $code = NULL, $exit = TRUE) {

		if(!empty($url)) {

			if(!preg_match('/^(http|https)/i', &$url, $match)) {

				if($url{0} !== '//') {

					$url = HTTP_URL . $url;
				}

				else {

					$url = HTTP_URL . substr(&$url, 1);
				}
			}

			if($top) {

				echo('<script>

								try {

									var isActive = window.top.$jabezPHP.config.jabezWebDeveloperIsActive;
								}

								catch(e) {

									var isActive = false;
								}

								if(isActive) {

									window.top.document.getElementById("iframe-jabezWebDeveloperContentOfPage").src = "' . $url . '";
								}

								else {

									window.top.location = "' . $url . '";
								}
					</script>');
			}

			else {

				echo("<script>window.location='" . $url . "';</script>");
			}
		}

		else {

			return FALSE;
		}

		if($exit) {

			exit(0);
		}

		return TRUE;
	}
}

class Request extends \Core\Libs\Http\Http {

	public function __construct() {

		
	}

	public function setHeaders($headers = NULL) {

		$this->headers = $headers;
	}

	public function setRequestHeaders() {

		try {

			$headers = headers_list();
		}

		catch(\Exception $e) {

			throw \Core\Uses\Exception('Error: Cabeçalhos já enviados.', E_WARNING, 100, __FILE__, __LINE__, $e->getMessage());
		}
	}
}

class Response extends \Core\Libs\Http\Http {

	private $stream = NULL;
	private $gzip = FALSE;
	private $deflate = FALSE;
	private $compressionLevel = 5;
	private $compressionType = NULL;

	protected $responseOfController = FALSE;
	protected $returnOfController = FALSE;
	protected $responseOfView = FALSE;
	protected $returnOfView = FALSE;
	protected $responseRender = TRUE;
	protected $responses = FALSE;
	protected $allContentToResponseOfRequest = TRUE;
	protected $contentToResponseOfRequest = 'responseOfRequest';
	protected static $containerTypeToResponse = NULL;

	public function __construct() {

		parent::__construct();
	}

	final public function setStream() {

		
	}

	final public function getStream() {

		
	}

	final public function getCompressionType() {

		
	}

	final public function setGzip() {

		
	}

	final public function getGzip() {

		
	}

	final public function setDeflate() {

		
	}

	final public function getDeflate() {

		
	}

	final public function setCompressionLevel() {

		
	}

	final public function getCompressionLevel() {

		
	}

	final public function compress() {

		
	}

	final public function setAllContentToResponseOfRequest($responseOfRequest = FALSE) {

		$this->allContentToResponseOfRequest = $responseOfRequest;
	}

	final public function isAllContentToResponseOfRequest() {

		return $this->allContentToResponseOfRequest;
	}

	final public function setContentToResponseOfRequest($method = 'responseOfRequest') {

		/*
		if($method === 'responseOfView') {

			$this->responseOfView = TRUE;
			$this->responseOfController = FALSE;
			$this->returnOfController = FALSE;
			$this->returnOfView = FALSE;
			$this->responseRender = FALSE;
			$this->responses = FALSE;
		}

		elseif($method === 'responseOfController') {

			$this->responseOfView = FALSE;
			$this->responseOfController = TRUE;
			$this->returnOfController = FALSE;
			$this->returnOfView = FALSE;
			$this->responseRender = FALSE;
			$this->responses = FALSE;
		}

		elseif($method === 'returnOfController') {

			$this->responseOfView = FALSE;
			$this->responseOfController = FALSE;
			$this->returnOfController = TRUE;
			$this->returnOfView = FALSE;
			$this->responseRender = FALSE;
			$this->responses = FALSE;
		}

		elseif($method === 'returnOfView') {

			$this->responseOfView = FALSE;
			$this->responseOfController = FALSE;
			$this->returnOfController = FALSE;
			$this->returnOfView = TRUE;
			$this->responseRender = FALSE;
			$this->responses = FALSE;
		}

		elseif($method === 'responseRender') {

			$this->responseOfView = FALSE;
			$this->responseOfController = FALSE;
			$this->returnOfController = FALSE;
			$this->returnOfView = FALSE;
			$this->responseRender = TRUE;
			$this->responses = FALSE;
		}

		else {

			$this->responseOfView = FALSE;
			$this->responseOfController = FALSE;
			$this->responseOfView = FALSE;
			$this->returnOfView = FALSE;
			$this->responseRender = FALSE;
			$this->responses = TRUE;
			$method = 'responses';
		}*/

		$this->contentToResponseOfRequest = $method;
		return $this;
	}

	final public function getContentToResponseOfRequest() {

		return $this->contentToResponseOfRequest;
	}

	final public function setContainerTypeToResponse($type = 'responseOfRequest') {

		self::$containerTypeToResponse = $type;
		return $this;
	}

	final public function getContainerTypeToResponse($type = 'responseOfRequest') {

		if(empty(self::$containerTypeToResponse)) {

			self::$containerTypeToResponse = $type;
		}

		return self::$containerTypeToResponse;
	}

	final public function disableCache() {

		@header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
		@header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
		@header('Cache-Control: no-store, no-cache, must-revalidate');
		@header('Cache-Control: post-check=0, pre-check=0', FALSE);
		@header('Pragma: no-cache');
	}
}

class Ajax extends \Core\Libs\Http\Response {

	protected $typesOfMessages = array('success', 'message', 'notice', 'alert', 'error', 'warning');
	protected $messages = array();
	protected static $isDevelopment = FALSE;
	protected static $isDebug = FALSE;

	public function setTypesOfMessages($typesOfMessages = array()) {

		if(!is_array($typesOfMessages)) {

			$typesOfMessages = array($typesOfMessages);
		}

		$this->typesOfMessages = $typesOfMessages;
		return $this;
	}

	public function getTypesOfMessages() {

		return $this->typesOfMessages;
	}

	public function getMessages() {

		return $this->messages;
	}

	public function isDevelopment() {

		return self::$isDevelopment;
	}

	public function isDebug() {

		return self::$isDebug;
	}
}

class AjaxRequest extends \Core\Libs\Http\Ajax {

	
}

class AjaxResponse extends \Core\Libs\Http\Ajax {

	private $readOnly = FALSE;
	private $jsonResponse = TRUE;
	private $jsonOptions = NULL;
	private $envResponse = FALSE;
	private $isSent = FALSE;

	final public function setReadOnly($readOnly = TRUE) {

		$this->readOnly = $readOnly;
		return $this;
	}

	final public function isReadOnly() {

		return $this->readOnly;
	}

	final public function setJsonResponse($jsonResponse = TRUE) {

		$this->jsonResponse = $jsonResponse;
		return $this;
	}

	final public function isJsonResponse() {

		return $this->jsonResponse;
	}

	final public function setJsonOptions($jsonOptions = NULL) {

		$this->jsonOptions = $jsonOptions;
		return $this;
	}

	final public function setEnvResponse($envResponse = TRUE) {

		$this->envResponse = $envResponse;
		return $this;
	}

	final public function getJsonOptions() {

		return $this->jsonOptions;
	}
	
	public function __construct($jsonResponse = TRUE, $jsonConfig = NULL) {

		$this->jsonResponse = $jsonResponse;
		$this->jsonOptions = $jsonConfig;
		self::$isDevelopment = \Core\Uses\Ler('Core.development.status');
		self::$isDebug = \Core\Uses\Ler('Core.debug.status');
	}

	final public function get($id = NULL) {

		if(is_array($this->messages) && array_key_exists($id, $this->messages)) {

			return $this->messages[$id];
		}

		return FALSE;
	}

	final public function add($id = NULL, $value = NULL, $options = array()) {

		if($this->readOnly) {

			return $this;
		}

		if(!empty($id) && ($this->envResponse || strtolower($id) !== 'response')) {

			$arrayData = array();

			if(!$this->envResponse) {

				$type = array_search($options['type'], $this->typesOfMessages);

				if(empty($type) || $type === FALSE) {

					$type = 'notice';
				}

				if(!is_array($options)) {

					$options = array('type' => $type);
				}

				else {

					$options['type'] = $type;
				}

				$development = self::$isDevelopment;
				$arrayData = array_merge(array('type' => 'notice', 'code' => NULL, 'severityCode' => NULL, 'severityName' => NULL, 'internal' => NULL, 'file' => NULL, 'line' => NULL, 'debugBackTrace' => NULL), $options);

				if($development) {

					$debug = self::$isDebug;
					$arrayData['development'] = $development;
					$arrayData['debug'] = $debug;

					if(empty($options['internal'])) {

						$arrayData['internal'] = \Core\Uses\getInternalError();
					}

					if(empty($options['file'])) {
	
						$arrayData['file'] = \Core\Uses\getErrorFile();
					}

					if(empty($options['line'])) {

						$arrayData['line'] = \Core\Uses\getErrorLine();
					}

					if(array_key_exists('debugBackTrace', &$options) && empty($options['debugBackTrace'])) {
	
						$arrayData['debugBackTrace'] = debug_backtrace(FALSE);
					}
				} 

				if(empty($options['code']) && $type !== 'success') {

					$arrayData['code'] = \Core\Uses\Exception()->getCode();
				}

				if(empty($options['severityCode']) && $type !== 'success') {

					$arrayData['severityCode'] = \Core\Uses\getSeverity();
				}

				if(empty($options['severityName']) && $type !== 'success') {
	
					$arrayData['severityName'] = \Core\Uses\getSeverityAsString();
				}
			}

			else {

				if(self::$isDevelopment) {

					$arrayData['development'] = self::$isDevelopment;
					$arrayData['debug'] = self::$isDebug;
				}
			}
/*
			$isForm = \Core\Libs\MasterObject\MasterObject::getRequest()->getElement(array());

			if(self) {

				
			}*/

			$this->messages[$id] = array('data' => $value, 'options' => $arrayData);
		}

		return $this;
	}

	final public function remove($id = NULL) {

		if($this->readOnly) {

			return;
		}

		if(is_array($this->messages) && array_key_exists($id, $this->messages)) {

			unset($this->messages[$id]);
			return TRUE;
		}

		return FALSE;
	}

	final public function send() {

		if($this->jsonResponse) {

			$this->jsonEncode();
			echo($this->messages);
		}

		else {

			echo($this->messages);
		}
	}

	final public function isSent() {

		return $this->isSent;
	}

	final public function jsonEncode($messages = NULL, $options = NULL) {

		$numArgs = func_num_args();

		if($numArgs === 1) {

			$this->messages = $messages;
		}

		elseif($numArgs > 1) {

			$this->messages = $messages;
			$this->jsonOptions = $options;
		}

		try {

			$this->messages = json_encode($this->messages, $this->jsonOptions);
		}

		catch(\Exception $e) {

			\Core\Uses\setSeverity(100);
			$this->messages = array('_jabezPHP' => array('data' => 'Erro: Problema ao codificar a mensagem para envio com JSON.', 'options' => array('development' => self::$isDevelopment, 'debug' => self::$isDebug, 'type' => 'error', 'internal' => \Core\Uses\getInternalError(), 'code' => json_last_error(), 'severityCode' => \Core\Uses\getSeverity(), 'severityName' => \Core\Uses\getSeverityAsString())));
		}
	}
}
?>